package com.wzdigit.wms.raw.service.asn.report;

import cn.hutool.core.collection.CollectionUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.wzdigit.framework.Shift;
import com.wzdigit.wms.basic.client.Pager;
import com.wzdigit.wms.basic.client.PagerInfo;
import com.wzdigit.wms.basic.enums.*;
import com.wzdigit.wms.basic.util.enums.SystemModuleEnum;
import com.wzdigit.wms.common.entity.ExcelExportConfig;
import com.wzdigit.wms.common.utils.QueryInUtil;
import com.wzdigit.wms.common.utils.ReportHttpExcel;
import com.wzdigit.wms.raw.client.request.asn.report.ortherasn.OrtherAsnRequest;
import com.wzdigit.wms.raw.client.response.asn.report.ortherasn.OrtherAsnDtlGoodsResponse;
import com.wzdigit.wms.raw.client.response.asn.report.ortherasn.OrtherAsnDtlResponse;
import com.wzdigit.wms.raw.client.response.asn.report.ortherasn.OrtherAsnExcel;
import com.wzdigit.wms.raw.client.response.asn.report.ortherasn.OrtherAsnResponse;
import com.wzdigit.wms.raw.client.response.asn.report.ortherasn.OrtherAsnEnums;
import com.wzdigit.wms.raw.mapper.asn.report.OrtherAsnMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.support.collections.RedisList;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 其他入库单Service
 * Created by zyf on 2021/6/9 18:34
 */
@Service
@Slf4j
public class OrtherAsnService {

    @Autowired
    private OrtherAsnMapper ortherAsnMapper;

    //报表导出
    @Transactional
    public void exportOrtherAsnReport(
            OrtherAsnRequest search,
            HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws Exception{
        ServletOutputStream out = null;
        XSSFWorkbook workbook = null;
        try {
            List<String> asnTypeList = AsnTypeEnum.getEnumBySystemModule(SystemModuleEnum.RAW);
            asnTypeList.remove("R14");
            asnTypeList.remove("R13");
            //查询其他入库单头List集合
            List<OrtherAsnResponse> asnResponseList = this.selectOrtherAsnHeader(search,asnTypeList,true);
            //获取HeaderId集合
            List<BigDecimal> headerIds =
                    asnResponseList.stream().map(t -> t.getAsnHeaderId()).collect(Collectors.toList());
            if (CollectionUtil.isEmpty(headerIds)){
                Shift.fatal("查无对于入库单记录!");
            }
            //获取其他入库单明细List集合
            List<OrtherAsnDtlResponse> asnDtlResponseList=new ArrayList<>();
            List<List<BigDecimal>> headerIdSplit = QueryInUtil.splitInParams(999, headerIds);
            for (List<BigDecimal> list : headerIdSplit) {
                asnDtlResponseList.addAll(this.selectOrtherAsnDtl(list));
            }
            List<ExcelExportConfig> headerConfigs = new ArrayList<>();
            //由于导出工具类采用了泛型，因此需要将两个集合调整为相同的结合
            List<OrtherAsnExcel> asnHeaderExcels = this.setAsnExcelHeader(asnResponseList);
            List<OrtherAsnExcel> asnDtlExcels = this.setAsnExcelDtl(asnDtlResponseList);
            //配置导出报表信息
            headerConfigs.add(new ExcelExportConfig("入库单号", "asnNo", 120));
            headerConfigs.add(new ExcelExportConfig("订单状态", "asnStatusString", 120));
            headerConfigs.add(new ExcelExportConfig("单据类型", "asnTypeString", 120));
            headerConfigs.add(new ExcelExportConfig("收货仓库", "whsName", 120));
            headerConfigs.add(new ExcelExportConfig("需求数量", "headerOrderQtys", 120));
            headerConfigs.add(new ExcelExportConfig("收货数量", "headerRcvQtys", 120));
            headerConfigs.add(new ExcelExportConfig("单据来源", "dataSource", 120));
            headerConfigs.add(new ExcelExportConfig("制单时间", "createTime", 120));
            headerConfigs.add(new ExcelExportConfig("审核时间", "asnApprovedTime", 120));
            headerConfigs.add(new ExcelExportConfig("制单人", "createUser", 120));
            headerConfigs.add(new ExcelExportConfig("审核人", "asnApprovedUser", 120));
            headerConfigs.add(new ExcelExportConfig("备注", "comment", 120));
            List<ExcelExportConfig> dtlConfigs = new ArrayList<>();
            dtlConfigs.add(new ExcelExportConfig("入库单号", "asnNo", 120));
            dtlConfigs.add(new ExcelExportConfig("行号", "asnLineNo", 120));
            dtlConfigs.add(new ExcelExportConfig("行状态", "asnLineStatus", 120));
            dtlConfigs.add(new ExcelExportConfig("物料编码", "skuCode", 120));
            dtlConfigs.add(new ExcelExportConfig("物料描述", "descCn", 120));
            dtlConfigs.add(new ExcelExportConfig("物料规格", "spec", 120));
            dtlConfigs.add(new ExcelExportConfig("关联单号", "poNo", 120));
            dtlConfigs.add(new ExcelExportConfig("关联单行号", "poLineNo", 120));
            dtlConfigs.add(new ExcelExportConfig("需求数量", "rcvQtyEa", 120));
            dtlConfigs.add(new ExcelExportConfig("入库数量", "rcvQty", 120));
            dtlConfigs.add(new ExcelExportConfig("单位", "unit", 120));
            dtlConfigs.add(new ExcelExportConfig("质检状态", "qcStatusString", 120));
            dtlConfigs.add(new ExcelExportConfig("检验结果", "qcResultString", 120));
            dtlConfigs.add(new ExcelExportConfig("检验单号", "inspNo", 120));
            dtlConfigs.add(new ExcelExportConfig("上架库位", "locDesc", 120));
            dtlConfigs.add(new ExcelExportConfig("创建人员", "createUser", 120));
            dtlConfigs.add(new ExcelExportConfig("创建时间", "createTime", 120));
            workbook = ReportHttpExcel.newListToExcel(asnHeaderExcels, headerConfigs, asnDtlExcels, dtlConfigs,"原材料入库单主档","原材料入库单明细");
            String userAgent = servletRequest.getHeader("USER-AGENT");
            String fileName = "原材料入库单";
            if (userAgent.contains("Mozilla")) {
                fileName = new String(fileName.getBytes(), "ISO8859-1");
            } else {
                fileName = URLEncoder.encode(fileName, "utf8");
            }
            servletResponse.setContentType("application/octet-stream");
            servletResponse.setHeader("Content-Disposition", "attachment;fileName=" + fileName + ".xlsx");
            servletResponse.flushBuffer();
            out = servletResponse.getOutputStream();
            workbook.write(out);

        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (out != null) {
                out.flush();
                out.close();
            }
            if(workbook != null) {
                workbook.close();
            }
        }
    }

    //分页查询其他入库单主页
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public PagerInfo<List<OrtherAsnResponse>> searchOrtherAsnHeader(
            OrtherAsnRequest search, Pager<?> pager){
        List<String> asnTypeList = AsnTypeEnum.getEnumBySystemModule(SystemModuleEnum.RAW);
        asnTypeList.remove("R14");
        asnTypeList.remove("R13");
        Page<OrtherAsnResponse> page = PageHelper.offsetPage(pager.getSkipCount(), pager.getMaxResultCount());
        List<OrtherAsnResponse> datas = this.selectOrtherAsnHeader(search,asnTypeList,false);
        PagerInfo<List<OrtherAsnResponse>> pagerInfo = new PagerInfo<>();
        pagerInfo.setTotalCount(page.getTotal());
        pagerInfo.setItems(datas);

        return pagerInfo;
    }

    //分页查询其他入库单明细
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public PagerInfo<List<OrtherAsnDtlResponse>> searchOrtherAsnDtl(
            BigDecimal asnHeaderId, Pager<?> pager){
        Page<OrtherAsnDtlResponse> page = PageHelper.offsetPage(pager.getSkipCount(), pager.getMaxResultCount());
        List<BigDecimal> asnHeaderIdList=new ArrayList<>();asnHeaderIdList.add(asnHeaderId);
        List<OrtherAsnDtlResponse> datas = this.selectOrtherAsnDtl(asnHeaderIdList);
        PagerInfo<List<OrtherAsnDtlResponse>> pagerInfo = new PagerInfo<>();
        pagerInfo.setTotalCount(page.getTotal());
        pagerInfo.setItems(datas);

        return pagerInfo;
    }

    //分页查询其他入库单序列
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public PagerInfo<List<OrtherAsnDtlGoodsResponse>> searchOrtherAsnDtlGoods(
             BigDecimal asnHeaderId, Pager<?> pager){
        List<BigDecimal> asnHeaderIdList=new ArrayList<>();asnHeaderIdList.add(asnHeaderId);
        List<BigDecimal> asnDtlIds = ortherAsnMapper.selectDtlIdByHeader(asnHeaderIdList);
        PagerInfo<List<OrtherAsnDtlGoodsResponse>> pagerInfo = new PagerInfo<>();
        if (CollectionUtil.isEmpty(asnDtlIds)){
            pagerInfo.setItems(null);
            return pagerInfo;
        }
        Page<OrtherAsnDtlGoodsResponse> page = PageHelper.offsetPage(pager.getSkipCount(), pager.getMaxResultCount());
        List<OrtherAsnDtlGoodsResponse> datas = this.selectOrtherAsnDtlGoods(asnDtlIds);

        pagerInfo.setTotalCount(page.getTotal());
        pagerInfo.setItems(datas);

        return pagerInfo;
    }

    //查询其他入库单主页【复用】
    private List<OrtherAsnResponse> selectOrtherAsnHeader(OrtherAsnRequest search,List<String> asnTypeList,
                                                          Boolean flag){
        //设置查询条件
        if (flag){
            //导出
            if (!CollectionUtil.isEmpty(search.getHeaderIds())){
                //复选框勾选时,设置其他查询条件为空,保留发货单集合
                search.setFilter(null);search.setAsnNo(null);search.setSkuId(null);search.setStatus(null);
                search.setBeginTime(null);search.setEndTime(null);search.setAsnType(null);
                search.setPoNo(null);search.setWhsCode(null);
            }else {
                search.setHeaderIds(null);
            }
        }else {
            //分页查询
            search.setHeaderIds(null);
        }


        if (search.getBeginTime()!=null){
            search.setBeginTimeDate(new Date(search.getBeginTime()));
        }
        if (search.getEndTime()!=null){
            search.setEndTimeDate(new Date(search.getEndTime()));
        }
        if (search.getFilter()!=null){
            search.setFilter(search.getFilter().replace(" ",""));
        }
        if (search.getAsnNo()!=null){
            search.setAsnNo(search.getAsnNo().replace(" ",""));
        }
        if (search.getPoNo()!=null){
            search.setPoNo(search.getPoNo().replace(" ",""));
        }
        List<OrtherAsnResponse> datas = ortherAsnMapper.selectAllHeader(search,asnTypeList);
        //设置返回信息
        for (OrtherAsnResponse data : datas) {
            if (data.getAsnType()!=null){
                AsnTypeEnum asnTypeEnum = AsnTypeEnum.getEnumByCode(data.getAsnType());
                if (asnTypeEnum!=null){
                    data.setAsnTypeString(asnTypeEnum.enumName);
                }
            }
            if (data.getStatus()!=null){
                AsnHeaderStatusEnum asnHeaderStatusEnum =
                        AsnHeaderStatusEnum.getEnumByCode(data.getStatus());
                if (asnHeaderStatusEnum!=null){
                    data.setAsnStatusString(asnHeaderStatusEnum.getEnumName());
                }
            }
        }
        return datas;
    }

    //查询其他入库单明细
   private List<OrtherAsnDtlResponse> selectOrtherAsnDtl(List<BigDecimal> asnHeaderIds){
        List<OrtherAsnDtlResponse> datas = ortherAsnMapper.selectAllDtl(asnHeaderIds);
        //设置返回信息
        for (OrtherAsnDtlResponse data : datas) {
            /*if (BigDecimal.ZERO.equals(data.getRcvQty())){
                data.setAsnLineStatus("待收货");
            }else if (data.getRcvQtyEa().compareTo(data.getRcvQty())==1){
                data.setAsnLineStatus(AsnDtlStatusEnum.PARTRECEIVE.enumName);
            } else {
                data.setAsnLineStatus(AsnDtlStatusEnum.WHOLERECEIVE.enumName);
            }*/
            if (data.getStatusInt()!=null){
                AsnDtlStatusEnum dtlStatusEnum = AsnDtlStatusEnum.getEnumByCode(data.getStatusInt());
                if (dtlStatusEnum!=null){
                    data.setAsnLineStatus(dtlStatusEnum.enumName);
                }
            }

            if (data.getQcResult()!=null){
                if (data.getQcResult().equals(QmsOqcStatusEnum.CHECK_ACCESS.getCode())){
                    data.setQcResultString(QmsOqcStatusEnum.JUDGE_RESULT_SUCCESS.getEnumByName());
                }
                if (data.getQcResult().equals(QmsOqcStatusEnum.CHECK_CONVICTED_BACK.getCode())){
                    data.setQcResultString(QmsOqcStatusEnum.JUDGE_RESULT_FAIL.getEnumByName());
                }
            }

            if (data.getQcStatus()!=null){
                if (data.getQcStatus().equals(QcStatusEnum.未创建质检单.getCode())){
                    data.setQcStatusString(QcStatusEnum.未创建质检单.getEnumByName());
                }else if (data.getQcStatus().equals(QcStatusEnum.已创建质检单.getCode())){
                    data.setQcStatusString(QcStatusEnum.已创建质检单.getEnumByName());
                }else if (data.getQcStatus().equals(QcStatusEnum.部分质检.getCode())){
                    data.setQcStatusString(QcStatusEnum.部分质检.getEnumByName());
                }else if (data.getQcStatus().equals(QcStatusEnum.全部质检.getCode())){
                    data.setQcStatusString(QcStatusEnum.全部质检.getEnumByName());
                }else if (data.getQcStatus().equals(QcStatusEnum.质检取消.getCode())){
                    data.setQcStatusString(QcStatusEnum.质检取消.getEnumByName());
                }else if (data.getQcStatus().equals(QcStatusEnum.质检关闭.getCode())){
                    data.setQcStatusString(QcStatusEnum.质检关闭.getEnumByName());
                }
            }
        }
        return datas;
    }

    //查询其他入库单序列【复用】
    private List<OrtherAsnDtlGoodsResponse> selectOrtherAsnDtlGoods(List<BigDecimal> asnDtlIds){
        List<OrtherAsnDtlGoodsResponse> datas = ortherAsnMapper.selectDtlGoodsByDtlIds(asnDtlIds);
        return datas;
    }

    //重设表头信息
    List<OrtherAsnExcel> setAsnExcelHeader(List<OrtherAsnResponse> headerList){
        List<OrtherAsnExcel> asnExcelList=new ArrayList<>();
        for (OrtherAsnResponse header : headerList) {
            OrtherAsnExcel asnExcel=new OrtherAsnExcel();
            asnExcel.setAsnNo(header.getAsnNo());
            asnExcel.setAsnStatusString(header.getAsnStatusString());
            asnExcel.setDataSource(header.getDataSource());
            asnExcel.setAsnTypeString(header.getAsnTypeString());
            asnExcel.setWhsName(header.getWhsName());
            asnExcel.setAsnApprovedTime(header.getAsnApprovedTime());
            asnExcel.setAsnApprovedUser(header.getAsnApprovedUser());
            asnExcel.setComment(header.getComment());
            asnExcel.setCreateUser(header.getCreateUser());
            asnExcel.setCreateTime(header.getCreateTime());
            asnExcel.setHeaderOrderQtys(header.getOrderQtys());
            asnExcel.setHeaderRcvQtys(header.getRcvQtys());
            asnExcelList.add(asnExcel);
        }
        return asnExcelList;
    }

    //重设明细信息
    List<OrtherAsnExcel> setAsnExcelDtl(List<OrtherAsnDtlResponse> dtlList){
        List<OrtherAsnExcel> asnExcelList=new ArrayList<>();
        for (OrtherAsnDtlResponse dtl : dtlList) {
            OrtherAsnExcel asnExcel=new OrtherAsnExcel();
            asnExcel.setAsnNo(dtl.getAsnNo());
            asnExcel.setAsnLineNo(dtl.getAsnLineNo());
            asnExcel.setAsnLineStatus(dtl.getAsnLineStatus());
            asnExcel.setSkuCode(dtl.getSkuCode());
            asnExcel.setDescCn(dtl.getDescCn());
            asnExcel.setSpec(dtl.getSpec());
            asnExcel.setPoNo(dtl.getPoNo());
            asnExcel.setPoLineNo(dtl.getPoLineNo());
            asnExcel.setRcvQtyEa(dtl.getRcvQtyEa());
            asnExcel.setRcvQty(dtl.getRcvQty());
            asnExcel.setQcStatusString(dtl.getQcStatusString());
            asnExcel.setUnit(dtl.getUnit());
            asnExcel.setQcResultString(dtl.getQcResultString());
            asnExcel.setInspNo(dtl.getInspNo());
            asnExcel.setLocDesc(dtl.getLocDesc());
            asnExcel.setCreateUser(dtl.getCreateUser());
            asnExcel.setCreateTime(dtl.getCreateTime());
            asnExcelList.add(asnExcel);
        }
        return asnExcelList;
    }

    //查询其他入库单单据类型下拉框
    public List<OrtherAsnEnums> getOrtherAsnEnumsList(){
        List<String> asnTypeList = AsnTypeEnum.getEnumBySystemModule(SystemModuleEnum.RAW);
        asnTypeList.remove("R14");
        asnTypeList.remove("R13");
        List<OrtherAsnEnums> datas=new ArrayList<>();
        for (String asnTypeString : asnTypeList) {
            AsnTypeEnum asnTypeEnum = AsnTypeEnum.getEnumByCode(asnTypeString);
            if (asnTypeEnum!=null){
                OrtherAsnEnums data=new OrtherAsnEnums();
                data.setCode(asnTypeString);
                data.setEnumName(asnTypeEnum.getEnumName());
                datas.add(data);
            }
        }
        return datas;
    }

    //查询其他入库单订单类型下拉框数据
    public List<Map<Integer,String>> getAsnStatusEnum(){
        List<Map<Integer,String>> result=new ArrayList<>();
        for (AsnHeaderStatusEnum value : AsnHeaderStatusEnum.values()){
            Map<Integer,String> map=new HashMap<>();
            map.put(value.code,value.enumName);
            result.add(map);
        }
        return result;
    }




}
